package org.oimwrapper.connectors;

import Thor.API.Security.*;
import com.thortech.util.logging.*;
import java.util.*;

/**
 * This contains methods for printing exceptions.
 */
public final class OIMExceptionHandler {

	/**
	 * This method provides pretty-printing for handling exceptions.
	 * 
	 * @param ClassLogger The logger from the invoking object.
	 * @param Error The exception that was caught.
	 * @param This A reference to the class type for the invoking object.
	 */
	public final static void handleException(Logger ClassLogger, Throwable Error, Class This) {
		try {
			if (ClassLogger.isInfoEnabled()) {
				synchronized (ClassLogger) {
					ClassLogger.info("-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~");
					ClassLogger.info("         Unexpected Exception Caught! ");
					ClassLogger.info("");
					Throwable inner = Error;
					while (inner.getCause() != null) {
						inner = inner.getCause();
					}
					ClassLogger.info("    Exception Type: " + Error.getClass().getName());
					ClassLogger.info(" Exception Message: " + (inner.getMessage() == null ? "<null>" : inner.getMessage()));
					ClassLogger.info("         Caused By: " + inner.getClass().getName());
					ClassLogger.info("  Inner Stacktrace: ", inner);
					ClassLogger.info("    Catching Class: " + This.getName());
					StackTraceElement[] elements = Error.getStackTrace();
					Map items = new TreeMap();
					for (int i = 0; i < elements.length; i++) {
						try {
							Class itemClass = Class.forName(elements[i].getClassName());
							Class superClass = itemClass;
							boolean include = false;
							List classes = new ArrayList();
							while (!include && superClass != null) {
								classes.add(superClass);
								Class[] compareTo = {OIMAdapterBase.class, OIMTaskBase.class, OIMRemoteClientBase.class};
								for (int j = 0; !include && j < compareTo.length; j++) {
									if (superClass.getName().equals(compareTo[j].getName())) {
										include = true;
									}
								}
								superClass = superClass.getSuperclass();
							}
							if (include) {
								for (Iterator iterator = classes.iterator(); iterator.hasNext(); ) {
									String jarFile = OIMCodeVersion.getJarFile((Class) iterator.next());
									if (items.get(jarFile) == null) {
										items.put(jarFile, OIMCodeVersion.getJarBuildDate(jarFile) + ", r" + OIMCodeVersion.getJarSvnRevision(jarFile));
									}
								}
							}
						} catch (ClassNotFoundException e) {
							break;
						}
					}
					for (Iterator iterator = items.keySet().iterator(); iterator.hasNext(); ) {
						String jarFile = (String) iterator.next();
						ClassLogger.info("    Referenced Jar: " + jarFile + " (" + (String) items.get(jarFile) + ")");
					}
					ClassLogger.info("     Security User: " + XLClientSecurityAssociation.getLoginSession().getUserName());
					ClassLogger.info("~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-");
				}
			} else {
				ClassLogger.error(Error.getClass().getName() + " : " + Error.getMessage());
			}
		} catch (Exception e) {
			Error.printStackTrace();
		}
	}
}